package com.softaria.promosite.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.softaria.promosite.client.ContentService;
import com.softaria.server.seo.StaticContenetRetriever;
import com.softaria.server.seo.StaticMenu;
import com.softaria.server.seo.StaticPagesFactory;
import com.softaria.windows.config.MenuConfiguration;
import com.softaria.windows.model.PerspectiveUrl;
import com.softaria.windows.model.ViewUrl;

public class ContentServiceImpl extends RemoteServiceServlet implements ContentService {

  private static final long serialVersionUID = 1L;

  private File dataDir;

  public String getTextContent(String path) throws IOException {

    if (path.indexOf('.') != -1) {
      return "Bad path: " + path + " Path must not contain dots";
    }

    return getFile(path + ".html");

  }

  private String getFile(String path) throws FileNotFoundException, UnsupportedEncodingException,
      IOException {

    File f = new File(dataDir, path);

    InputStream is = new FileInputStream(f);

    try {

      InputStreamReader isr = new InputStreamReader(is, "utf-8");

      char buf[] = new char[4096];

      StringBuffer str = new StringBuffer();

      for (;;) {
        int length = isr.read(buf);
        if (length > 0) {
          str.append(buf, 0, length);
        } else {
          break;
        }
      }

      return str.toString();

    } finally {
      is.close();
    }
  }

  public MenuConfiguration getMenuConfiguration() throws IOException {

    FileInputStream menuStream = new FileInputStream(new File(dataDir, "menu.xml"));
    try {

      XmlMenuRepresentation config = XmlMenuRepresentation.createFromXml(menuStream);

      return config.createMenuConfiguration();
    } finally {
      menuStream.close();
    }

  }

  @Override
  public void init(ServletConfig config) throws ServletException {
	//System.out.println("content service impl is loaded on startup");  
	  
    super.init(config);

    dataDir = new File(config.getServletContext().getRealPath("WEB-INF/data"));

    MenuConfiguration mc;
    try {
      mc = getMenuConfiguration();
      StaticMenu staticMenu = new StaticMenu(mc);
      StaticPagesFactory.getInstance().setMenu(staticMenu);
    } catch (IOException e1) {
      e1.printStackTrace();
    }

    StaticContenetRetriever contentRetriever = new StaticContenetRetriever() {

      public String retrieveStaticContent(PerspectiveUrl url) {
        if (url.isView()) {
          ViewUrl vurl = (ViewUrl) url;

          String path = getParameter(vurl, "path");

          if (path != null) {
            try {
              return getTextContent(path);
            } catch (IOException e) {
              e.printStackTrace();
              return "";
            }
          }
        }
        return "";
      }

      public String retrieveDescription(PerspectiveUrl url) {
        if (url.isView()) {
          ViewUrl vurl = (ViewUrl) url;

          String path = getParameter(vurl, "path");

          if (path != null) {
            try {
              return getFile(path + ".desc");
            } catch (IOException e) {
              e.printStackTrace();
              return "";
            }
          }
        }
        return "";
      }

      public String retrieveKeywords(PerspectiveUrl url) {
        if (url.isView()) {
          ViewUrl vurl = (ViewUrl) url;

          String path = getParameter(vurl, "path");

          if (path != null) {
            try {
              return getFile(path + ".keywords");
            } catch (IOException e) {
              e.printStackTrace();
              return "";
            }
          }
        }
        return "";
      }

    };

    StaticPagesFactory.getInstance().setContentRetriever(contentRetriever);
  }

  private String getParameter(ViewUrl vurl, String name) {
    Map<String, List<String>> params = parseParameters(vurl.getParameters());

    if(params == null) return null;
    
    List<String> values = params.get(name);

    if ((values != null) && (values.size() > 0)) {
      return values.get(0);
    } else {
      return null;
    }
  }

  private static Map<String, List<String>> parseParameters(String qs) {
    if (qs == null)
      return null;

    qs = qs.trim();
    if (qs.length() == 0)
      return null;

    Map<String, List<String>> out = new HashMap<String, List<String>>();

    for (String kvPair : qs.split("&")) {
      String[] kv = kvPair.split("=", 2);
      if (kv[0].length() == 0) {
        continue;
      }

      List<String> values = out.get(kv[0]);
      if (values == null) {
        values = new ArrayList<String>();
        out.put(kv[0], values);
      }

      values.add(kv.length > 1 ? kv[1] : "");
    }

    return out;

  }

}
